/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.hnilica.cisteniulic.dao;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import net.hnilica.cisteniulic.dto.TerminCisOri;
import net.hnilica.cisteniulic.dto.TerminCisOriId;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;

/**
 *
 * @author swosh
 */
public class TerminDAO {

    private static EntityManagerFactory emf = Emf.getInstance();
    private Logger log = Logger.getLogger(getClass().getName());

    public TerminDAO() {
    }

    /**
     * @param termin
     * @param collTermin
     * @return
     * @throws TerminDAOException
     */
    public boolean saveTermin(TerminCisOri termin) throws Exception {
        EntityManager em = emf.createEntityManager();
        if (termin == null || termin.getNazAkce() == null || termin.getNazUlice() == null
                || termin.getCisOrientacni() == null) {
            throw new Exception("Termín, který se má uložit, "
                    + "není správně definován. Termín má tyto hodnoty:" + termin.toString());
        }
        Subject subject = SecurityUtils.getSubject();
        subject.checkRole("admin");
        em.getTransaction().begin();
        TerminCisOri terminFromDB = em.find(TerminCisOri.class, new TerminCisOriId(termin.getNazUlice(), termin.getNazAkce()));
        if (terminFromDB != null && ((termin.getNazAkce().equals(terminFromDB.getNazAkce())
                && termin.getNazUlice().equals(terminFromDB.getNazUlice())))) {
            em.getTransaction().rollback();
            throw new Exception("Chyba při ukládání temínu. "
                    + "Termíny nemohou mít shodné názvy akcí a zároveň ulic. "
                    + "Termín má tyto hodnoty: " + termin.toStringNotEndDot()
                    + "Termín z databáze má tyto hodnoty: " + terminFromDB.toString());
        }
        try {

            em.persist(termin);
            em.getTransaction().commit();

        } catch (Exception ex) {
            em.getTransaction().rollback();
            log.log(Level.WARNING, ex.getMessage());
            throw new Exception("Chyba při ukládání temínů. Termín má tyto hodnoty:" + termin.toString()
                    + "Chyba zní:" + ex.getMessage());
        } finally {
            em.close();
        }
        return true;
    }

    public TerminCisOri getTermin(String nazUlice, String nazAkce) {
        EntityManager em = emf.createEntityManager();
        if (nazAkce == null || nazUlice == null) {
            return new TerminCisOri();
        }
        try {
            TerminCisOriId id = new TerminCisOriId(nazUlice, nazAkce);
            TerminCisOri terminCisOri = em.find(TerminCisOri.class, id);
            return terminCisOri;
        } catch (Exception e) {
            log.log(Level.WARNING, "Chyba při vybírání temínů. ", e.getMessage());
            return new TerminCisOri();
        } finally {
            em.close();
        }
    }

    public boolean updateTermin(TerminCisOri terminOld, TerminCisOri terminNew) throws Exception {
        EntityManager em = emf.createEntityManager();

        if (terminOld.getNazAkce() == null || terminOld.getNazUlice() == null
                || terminOld.getCisOrientacni() == null) {

            throw new Exception("Termín, který se má aktualizovat, "
                    + "není správně definován. Má tyto hodnoty:" + terminOld.toString());
        }
        if (terminNew.getNazAkce() == null && terminNew.getNazUlice() == null
                && terminNew.getTerCis() == null && terminNew.getCisOrientacni() == null) {
            throw new Exception("Není zadán ani jeden údaj k aktualizaci. ");
        }
        Subject subject = SecurityUtils.getSubject();
        subject.checkRole("admin");
        em.getTransaction().begin();
        TerminCisOri terminFromDB = em.find(TerminCisOri.class, new TerminCisOriId(terminOld.getNazUlice(), terminOld.getNazAkce()));
        if (terminFromDB == null || !((terminOld.getNazAkce().equals(terminFromDB.getNazAkce())
                && terminOld.getNazUlice().equals(terminFromDB.getNazUlice())))) {
            em.getTransaction().rollback();
            throw new Exception("Termín s hodnotami " + terminOld.toStringNotEndDot() + "  neexistuje. Nemůže být aktualizován na hodnoty. " + terminNew.toString());
        }
        try {

            em.merge(terminNew);
            em.getTransaction().commit();

        } catch (Exception ex) {
            em.getTransaction().rollback();
            log.log(Level.SEVERE, ex.getMessage());
            throw new Exception("Chyba při aktualizaci temínů." + ex.getMessage()
                    + " Termín s hodnotami " + terminOld.toStringNotEndDot() + "  se neaktualizoval na hodnoty. " + terminNew.toString());
        } finally {
            em.close();
        }
        return true;
    }

    public boolean deleteTermin(TerminCisOri termin) throws Exception {
        EntityManager em = emf.createEntityManager();
        if (termin == null || termin.getNazAkce() == null || termin.getNazUlice() == null
                || termin.getCisOrientacni() == null) {

            throw new Exception("Termín, který se má smazat, "
                    + "není správně definován. Termín má tyto hodnoty:" + termin.toString());
        }
        Subject subject = SecurityUtils.getSubject();
        subject.checkRole("admin");
        em.getTransaction().begin();
        TerminCisOri terminFromDB = em.find(TerminCisOri.class, new TerminCisOriId(termin.getNazUlice(), termin.getNazAkce()));
        if (terminFromDB == null || !((termin.getNazAkce().equals(terminFromDB.getNazAkce())
                && termin.getNazUlice().equals(terminFromDB.getNazUlice())))) {
                        em.getTransaction().rollback();
            throw new Exception("Termín nebyl smazán. "
                    + "Není v databázi. Termín má tyto hodnoty:" + termin.toString());
        }
        try {

            em.remove(terminFromDB);
            em.getTransaction().commit();

        } catch (Exception ex) {
                        em.getTransaction().rollback();
            log.log(Level.SEVERE, ex.getMessage());
            throw new Exception("Chyba při mazání temínu. Termín má tyto hodnoty:" + termin.toString()
                    + "Chyba zní:" + ex.getMessage());
        } finally {
            em.close();
        }
        return true;
    }

}
